﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using YonYou.U8.IN.Forms.Properties;

namespace YonYou.U8.IN.Forms
{
	[DefaultEvent("SelectedIndexChanged"), DefaultProperty("Items")]
	public class MetroToolBar : Control
    {
        
        private Image m_NormalImage = Resources.toolbar_Normal;
        private Image m_PushedImage = Resources.toolbar;
        private Image m_HoverImage = Resources.toolbar;
		private ToolItemCollection m_Items = null;
        private Size m_ItemSize = new Size(72, 70);
        private Size m_ImageSize = new Size(44, 44);
        private int m_ItemSpace = 10;
        private int m_SelectedIndex = 0;
        private MetroToolItem m_SelectedItem = null;
        private Image m_Logo = null;

        public MetroToolBar()
        {
            base.SetStyle(ControlStyles.UserPaint | ControlStyles.ResizeRedraw | ControlStyles.Selectable | ControlStyles.SupportsTransparentBackColor | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
            base.SetStyle(ControlStyles.Opaque, false);
            base.UpdateStyles();
            this.Initialize();
        }
        private void Initialize()
        {
            this.BackColor = Color.Transparent;
        }
        public void Select(MetroToolItem item)
        {
            if (this.Items.Contains(item))
            {
                int indexOfRange = this.Items.GetIndexOfRange(item);
                SelectedItemEventArgs selectedItemEventArgs = new SelectedItemEventArgs(item, indexOfRange);
                this.OnSelectedItemChanging(selectedItemEventArgs);
                if (!selectedItemEventArgs.Cancel)
                {
                    this.m_SelectedItem = item;
                    this.OnSelectedItemChanged(selectedItemEventArgs);
                    this.m_SelectedIndex = indexOfRange;
                    this.OnSelectedIndexChanged(selectedItemEventArgs);
                    item.MouseState = MouseState.Up;
                    base.Invalidate();
                }
            }
        }
		//定义委托
		public delegate void SelectedItemChangingHandle(object sender, SelectedItemEventArgs e);
		//定义事件
		public event SelectedItemChangingHandle EventSelectedItemChanging;


		public virtual void OnSelectedItemChanging(SelectedItemEventArgs e)
        {
			if (EventSelectedItemChanging != null)
				EventSelectedItemChanging(this, e);
		}
		//定义委托
		public delegate void SelectedItemChangedHandle(object sender, SelectedItemEventArgs e);
		//定义事件
		public event SelectedItemChangedHandle EventSelectedItemChanged;

		public virtual void OnSelectedItemChanged(SelectedItemEventArgs e)
        {
			if (EventSelectedItemChanged != null)
				EventSelectedItemChanged(this, e);
		}
		//定义委托
		public delegate void SelectedIndexChangedHandle(object sender, SelectedItemEventArgs e);
		//定义事件
		public event SelectedIndexChangedHandle EventSelectedIndexChanged;


		public virtual void OnSelectedIndexChanged(SelectedItemEventArgs e)
        {
			if (EventSelectedIndexChanged != null)
				EventSelectedIndexChanged(this, e);
		}
		protected override void OnPaint(PaintEventArgs e)
		{
			base.OnPaint(e);
			Graphics graphics = e.Graphics;
			graphics.SmoothingMode = SmoothingMode.AntiAlias;
			int num = base.Padding.Left + 15;
			int y = base.Height - this.m_ItemSize.Height;
			foreach (MetroToolItem metroToolItem in this.Items)
			{
				Rectangle rectangle = new Rectangle(num, y, this.m_ItemSize.Width, this.m_ItemSize.Height);
				if (!base.DesignMode)
				{
					metroToolItem.Rectangle = rectangle;
					Rectangle rect = new Rectangle(rectangle.X - 2, rectangle.Y, rectangle.Width + 4, rectangle.Height);
					if (metroToolItem != this.SelectedItem)
					{
						if (metroToolItem.MouseState == MouseState.Normal || metroToolItem.MouseState == MouseState.Leave)
						{
							graphics.DrawImage(this.m_NormalImage, rectangle);
						}
						else if (metroToolItem.MouseState == MouseState.Move || metroToolItem.MouseState == MouseState.Up)
						{
							graphics.DrawImage(this.m_HoverImage, rect);
						}
						else if (metroToolItem.MouseState == MouseState.Down)
						{
							graphics.DrawImage(this.m_PushedImage, rect);
						}
					}
					else
					{
						graphics.DrawImage(this.m_PushedImage, rect);
					}
				}
				if (metroToolItem.Image != null)
				{
					Rectangle rect2 = default(Rectangle);
					rect2.X = rectangle.X + (rectangle.Width - this.m_ImageSize.Width) / 2;
					rect2.Y = rectangle.Y;
					rect2.Size = this.m_ImageSize;
					graphics.DrawImage(metroToolItem.Image, rect2);
				}
				if (!string.IsNullOrEmpty(metroToolItem.Text))
				{
					Rectangle bounds = this.CountTextRectangle(graphics, metroToolItem, rectangle);
					TextFormatFlags flags = TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter;
					TextRenderer.DrawText(graphics, metroToolItem.Text, this.Font, bounds, this.ForeColor, flags);
				}
				num += rectangle.Width + this.m_ItemSpace;
			}
			if (this.Logo != null)
			{
				Rectangle clientRectangle = base.ClientRectangle;
				int width = this.Logo.Width;
				int num2 = (this.Logo.Height > clientRectangle.Height - 10) ? (clientRectangle.Height - 10) : this.Logo.Height;
				int x = clientRectangle.Right - width - 20;
				int y2 = clientRectangle.Top + (clientRectangle.Height - num2) / 2;
				Rectangle rect3 = new Rectangle(x, y2, width, num2);
				graphics.DrawImage(this.Logo, rect3);
			}
		}

		private Rectangle CountTextRectangle(Graphics g, MetroToolItem item, Rectangle itemRect)
		{
			SizeF sizeF = g.MeasureString(item.Text, this.Font);
			return new Rectangle
			{
				X = itemRect.X + (int)(((float)this.m_ItemSize.Width - sizeF.Width) / 2f) + 2,
				Y = itemRect.Bottom - (int)(((float)(itemRect.Height - this.m_ImageSize.Height) - sizeF.Height) / 2f + sizeF.Height),
				Height = (int)sizeF.Height,
				Width = (int)sizeF.Width
			};
		}

		protected override void OnMouseMove(MouseEventArgs e)
		{
			base.OnMouseMove(e);
			if (!base.DesignMode)
			{
				Point location = e.Location;
				foreach (MetroToolItem metroToolItem in this.Items)
				{
					if (metroToolItem.MouseState != MouseState.Down)
					{
						if (metroToolItem.Rectangle.Contains(location))
						{
							metroToolItem.MouseState = MouseState.Move;
							base.Invalidate(metroToolItem.Rectangle);
						}
						else
						{
							metroToolItem.MouseState = MouseState.Leave;
							base.Invalidate(metroToolItem.Rectangle);
						}
					}
				}
			}
		}

		protected override void OnMouseLeave(EventArgs e)
		{
			base.OnMouseLeave(e);
			if (!base.DesignMode)
			{
				foreach (MetroToolItem metroToolItem in this.Items)
				{
					if (metroToolItem != this.SelectedItem)
					{
						metroToolItem.MouseState = MouseState.Leave;
						base.Invalidate(metroToolItem.Rectangle);
					}
				}
			}
		}

		protected override void OnMouseDown(MouseEventArgs e)
		{
			base.OnMouseDown(e);
			if (!base.DesignMode)
			{
				Point location = e.Location;
				foreach (MetroToolItem metroToolItem in this.Items)
				{
					if (metroToolItem.Rectangle.Contains(location))
					{
						if (metroToolItem != this.SelectedItem)
						{
							metroToolItem.MouseState = MouseState.Up;
							base.Invalidate(metroToolItem.Rectangle);
						}
					}
					else
					{
						metroToolItem.MouseState = MouseState.Normal;
						base.Invalidate(metroToolItem.Rectangle);
					}
				}
			}
		}

		protected override void OnMouseUp(MouseEventArgs e)
		{
			base.OnMouseUp(e);
			if (!base.DesignMode)
			{
				Point location = e.Location;
				foreach (MetroToolItem metroToolItem in this.Items)
				{
					if (metroToolItem != this.SelectedItem)
					{
						if (metroToolItem.Rectangle.Contains(location))
						{
							int indexOfRange = this.Items.GetIndexOfRange(metroToolItem);
							SelectedItemEventArgs selectedItemEventArgs = new SelectedItemEventArgs(metroToolItem, indexOfRange);
							this.OnSelectedItemChanging(selectedItemEventArgs);
							if (!selectedItemEventArgs.Cancel)
							{
								this.m_SelectedItem = metroToolItem;
								this.OnSelectedItemChanged(selectedItemEventArgs);
								this.m_SelectedIndex = indexOfRange;
								this.OnSelectedIndexChanged(selectedItemEventArgs);
								metroToolItem.MouseState = MouseState.Up;
								base.Invalidate();
							}
						}
					}
				}
			}
		}

		[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [EditorBrowsable(EditorBrowsableState.Always)]
        [Description("工具栏中的项")]
        public ToolItemCollection Items
        {
            get
            {
                if (this.m_Items == null)
                {
                    this.m_Items = new ToolItemCollection(this);
                }
                return this.m_Items;
            }
        }
        [Description("Item 的大小")]
        public Size ItemSize
        {
            get
            {
                return this.m_ItemSize;
            }
        }

        [Description("项与项之间的间隔")]
        public int ItemSpace
        {
            get
            {
                return this.m_ItemSpace;
            }
            set
            {
                this.m_ItemSpace = value;
                base.Invalidate();
            }
        }

        [Description("当前选中的 Item")]
        [Browsable(false)]
        public MetroToolItem SelectedItem
        {
            get
            {
                if (this.m_SelectedItem == null && this.Items.Count != 0)
                {
                    this.m_SelectedItem = this.Items[0];
                }
                return this.m_SelectedItem;
            }
        }

        [Description("选中 Item 的索引")]
        [Browsable(false)]
        public int SelectedIndex
        {
            get
            {
                return this.m_SelectedIndex;
            }
        }

        protected override Size DefaultSize
        {
            get
            {
                return new Size(300, 72);
            }
        }

        public Image Logo
        {
            get
            {
                return this.m_Logo;
            }
            set
            {
                this.m_Logo = value;
            }
        }

    }
}
